int errors = 0;
int shadow_refcounts = !!shadow_mode_refcounts(d);
int shadow_enabled = !!shadow_mode_enabled(d);
- int l2limit;
+
+ int l2limit( unsigned long mfn )
+ {
+
+ if ( shadow_mode_external(d) )
+ return L2_PAGETABLE_ENTRIES;
+
+#ifdef __i386__
+#ifdef CONFIG_X86_PAE
+ /* 32b PAE */
+ if ( (( frame_table[mfn].u.inuse.type_info & PGT_va_mask )
+ >> PGT_va_shift) == 3 )
+ return l2_table_offset(HYPERVISOR_VIRT_START);
+ else
+ return L2_PAGETABLE_ENTRIES;
+#else
+ /* 32b non-PAE */
+ return DOMAIN_ENTRIES_PER_L2_PAGETABLE;
+#endif
+#else
+ /* 64b */
+ return 0; /* XXX x86/64 XXX */
+#endif
+ }
void _adjust(struct pfn_info *page, int adjtype ADJUST_EXTRA_ARGS)
{
void adjust_l2_page(unsigned long mfn, int shadow)
{
- unsigned long *pt = map_domain_page(mfn);
+ l2_pgentry_t *pt = map_domain_page(mfn);
int i;
u32 page_type;
- for ( i = 0; i < l2limit; i++ )
+ for ( i = 0; i < l2limit(mfn); i++ )
{
- if ( pt[i] & _PAGE_PRESENT )
+ if ( l2e_get_flags(pt[i]) & _PAGE_PRESENT )
{
- unsigned long l1mfn = pt[i] >> PAGE_SHIFT;
+ unsigned long l1mfn = l2e_get_pfn(pt[i]);
struct pfn_info *l1page = pfn_to_page(l1mfn);
if ( noisy )
if ( shadow_mode_translate(d) && !shadow_mode_external(d) )
{
unsigned long hl2mfn =
- pt[l2_table_offset(LINEAR_PT_VIRT_START)] >> PAGE_SHIFT;
+ l2e_get_pfn(pt[l2_table_offset(LINEAR_PT_VIRT_START)]);
struct pfn_info *hl2page = pfn_to_page(hl2mfn);
adjust(hl2page, 0);
}
void adjust_hl2_page(unsigned long hl2mfn)
{
- unsigned long *pt = map_domain_page(hl2mfn);
+ l2_pgentry_t *pt = map_domain_page(hl2mfn);
int i;
- for ( i = 0; i < l2limit; i++ )
+ for ( i = 0; i < l2limit(hl2mfn); i++ )
{
- if ( pt[i] & _PAGE_PRESENT )
+ if ( l2e_get_flags(pt[i]) & _PAGE_PRESENT )
{
- unsigned long gmfn = pt[i] >> PAGE_SHIFT;
+ unsigned long gmfn = l2e_get_pfn(pt[i]);
struct pfn_info *gpage = pfn_to_page(gmfn);
if ( gmfn < 0x100 )
void adjust_l1_page(unsigned long l1mfn)
{
- unsigned long *pt = map_domain_page(l1mfn);
+ l1_pgentry_t *pt = map_domain_page(l1mfn);
int i;
for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
{
- if ( pt[i] & _PAGE_PRESENT )
+ if ( l1e_get_flags(pt[i]) & _PAGE_PRESENT )
{
- unsigned long gmfn = pt[i] >> PAGE_SHIFT;
+ unsigned long gmfn = l1e_get_pfn(pt[i]);
struct pfn_info *gpage = pfn_to_page(gmfn);
if ( gmfn < 0x100 )
if ( noisy )
{
- if ( pt[i] & _PAGE_RW )
+ if ( l1e_get_flags(pt[i]) & _PAGE_RW )
{
// If it's not a writable page, complain.
//
}
}
- adjust(gpage, (pt[i] & _PAGE_RW) ? 1 : 0);
+ adjust(gpage, (l1e_get_flags(pt[i]) & _PAGE_RW) ? 1 : 0);
}
}
}
}
-#ifdef __i386__
- if ( shadow_mode_external(d) )
- l2limit = L2_PAGETABLE_ENTRIES;
- else
- l2limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE;
-#else
- l2limit = 0; /* XXX x86/64 XXX */
-#endif
-
adjust_for_pgtbase();
adjust_guest_pages();
unsigned long mfn)
{
struct pfn_info *page = &frame_table[mfn];
- unsigned long *pt = map_domain_page(mfn);
+ l1_pgentry_t *pt = map_domain_page(mfn);
int i;
for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
{
- if ( (pt[i] & _PAGE_PRESENT) && ((pt[i] >> PAGE_SHIFT) == xmfn) )
+ if ( (l1e_get_flags(pt[i]) & _PAGE_PRESENT) &&
+ (l1e_get_pfn(pt[i]) == xmfn) )
printk(" found dom=%d mfn=%lx t=%" PRtype_info " c=%08x "
- "pt[i=%x]=%lx\n",
+ "pt[i=%x]=%" PRIpte "\n",
d->domain_id, mfn, page->u.inuse.type_info,
- page->count_info, i, pt[i]);
+ page->count_info, i, l1e_get_intpte(pt[i]));
}
unmap_domain_page(pt);
//
free_shadow_pages(d);
- /*
- * Tear down its counts by disassembling its page-table-based ref counts.
- * Also remove CR3's gcount/tcount.
- * That leaves things like GDTs and LDTs and external refs in tact.
- *
- * Most pages will be writable tcount=0.
- * Some will still be L1 tcount=0 or L2 tcount=0.
- * Maybe some pages will be type none tcount=0.
- * Pages granted external writable refs (via grant tables?) will
- * still have a non-zero tcount. That's OK.
- *
- * gcounts will generally be 1 for PGC_allocated.
- * GDTs and LDTs will have additional gcounts.
- * Any grant-table based refs will still be in the gcount.
- *
- * We attempt to grab writable refs to each page (thus setting its type).
- * Immediately put back those type refs.
- *
- * Assert that no pages are left with L1/L2/L3/L4 type.
- */
- audit_adjust_pgtables(d, -1, 1);
-
d->arch.shadow_mode = mode;
if ( shadow_mode_refcounts(d) )
{
- struct list_head *list_ent = d->page_list.next;
- while ( list_ent != &d->page_list )
- {
- struct pfn_info *page = list_entry(list_ent, struct pfn_info, list);
+ struct list_head *list_ent;
+
+ /*
+ * Tear down its counts by disassembling its page-table-based refcounts
+ * Also remove CR3's gcount/tcount.
+ * That leaves things like GDTs and LDTs and external refs in tact.
+ *
+ * Most pages will be writable tcount=0.
+ * Some will still be L1 tcount=0 or L2 tcount=0.
+ * Maybe some pages will be type none tcount=0.
+ * Pages granted external writable refs (via grant tables?) will
+ * still have a non-zero tcount. That's OK.
+ *
+ * gcounts will generally be 1 for PGC_allocated.
+ * GDTs and LDTs will have additional gcounts.
+ * Any grant-table based refs will still be in the gcount.
+ *
+ * We attempt to grab writable refs to each page thus setting its type
+ * Immediately put back those type refs.
+ *
+ * Assert that no pages are left with L1/L2/L3/L4 type.
+ */
+ audit_adjust_pgtables(d, -1, 1);
+
+
+ for (list_ent = d->page_list.next; list_ent != &d->page_list;
+ list_ent = page->list.next) {
+
+ struct pfn_info *page = list_entry(list_ent,
+ struct pfn_info, list);
if ( !get_page_type(page, PGT_writable_page) )
BUG();
put_page_type(page);
* We use tlbflush_timestamp as back pointer to smfn, and need to
* clean up it.
*/
- if ( shadow_mode_external(d) )
+ if (shadow_mode_external(d))
page->tlbflush_timestamp = 0;
- list_ent = page->list.next;
}
+
+ audit_adjust_pgtables(d, 1, 1);
+
}
- audit_adjust_pgtables(d, 1, 1);
-
return 0;
nomem: